﻿using System;
using System.Collections.Generic;
using System.Xml.XPath;
using System.Linq;
using SocialFront.Entities;
using SocialFront.Providers.Comment;
using SocialFront.Providers.Image;
using SocialFront.Providers.Media;
using SocialFront.Providers.Member;
using umbraco;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.media;
using umbraco.cms.businesslogic.relation;
using umbraco.cms.businesslogic.web;
using umbraco.presentation.nodeFactory;
using Media=umbraco.cms.businesslogic.media.Media;
using apiRelation = umbraco.cms.businesslogic.relation;

namespace SocialFront.Provider.Umbraco
{
    public class UmbracoImage : ImageBase
    {
        /// <summary>
        /// Creates the image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <returns></returns>
        public override Image CreateImage(Image image)
        {
            RelationType relationType = RelationType.GetByAlias("relateMemberToGalleryDocType");
            apiRelation.Relation[] relations = apiRelation.Relation.GetRelations(MemberProvider.Provider.GetCurrentMember().Id, relationType);
            if (relations.Count() > 1)
            {
                throw new Exception("Too many relateMemberToGalleryDocType relationships in database for user " + MemberProvider.Provider.GetCurrentMember().LoginName);
            }
            Document newDocument = Document.MakeNew(image.Title, DocumentType.GetByAlias("sfImageEntry"), User.GetUser(0), relations[0].Child.Id);
            newDocument.getProperty("title").Value = image.Title;
            newDocument.getProperty("pageTitle").Value = image.Title;
            newDocument.getProperty("content").Value = image.Content;
            newDocument.getProperty("mediaItem").Value = image.Media.Id;
            if (Config.sfPublishImageOnSave)
                newDocument.getProperty("enabled").Value = true;
            else
                newDocument.getProperty("enabled").Value = false;
            TagProvider.Provider.AddTags(image.Tags, newDocument.Id);
            newDocument.Save();
            newDocument.Publish(new User(0));
            library.UpdateDocumentCache(newDocument.Id);

            return ConvertNodeToImage(new Node(newDocument.Id));
        }

        public override Image UpdateImage(Image image)
        {
            throw new NotImplementedException();
        }

        public override int DeleteImage(int id)
        {
            throw new NotImplementedException();
        }

        public override int DeleteImage(Image image)
        {
            throw new NotImplementedException();
        }

        public override Image GetImageById(int id)
        {
            Node node = new Node(id);
            Image image = ConvertNodeToImage(node);

            return image;
        }

        public override XPathNodeIterator GetImageXmlById(int id)
        {
            throw new NotImplementedException();
        }

        public override List<Image> GetAllImages()
        {
            return GetAllImages(i => i.Name);
        }

        /// <summary>
        /// Gets all images.
        /// </summary>
        /// <returns></returns>
        public override List<Image> GetAllImages<T>(Func<Image, T> sortField)
        {
            return GetAllImages(null, sortField);
        }

        public override List<Image> GetAllImages<T>(int? pageSize, Func<Image, T> sortField)
        {
            return GetAllImages(pageSize, null, sortField);
        }

        public override List<Image> GetAllImages<T>(int? pageSize, int? page, Func<Image, T> sortField)
        {
            int total;
            return GetAllImages(pageSize, page, out total, sortField);
        }

        public override List<Image> GetAllImages<T>(int? pageSize, int? page, out int total, Func<Image, T> sortField)
        {
            total = 0;
            Node node = new Node(-1);
            List<Node> nodes = NodeHelper.GetNodesByAliasType(node, "sfImageEntry");
            List<Image> images = ConvertNodesToImages(nodes);
            images = images.OrderByDescending(sortField).ToList();
            if (pageSize.HasValue && page.HasValue)
                images = images.OrderByDescending(sortField).Skip((page.Value - 1) * pageSize.Value).Take(pageSize.Value).ToList();
            else if(pageSize.HasValue)
                images = images.OrderByDescending(sortField).Take(pageSize.Value).ToList();

            //images = images.OrderByDescending(sortField).ToList();

            total = images.Count;
            return images;
        }

        public override List<Image> GetImagesByMember(int id)
        {
            RelationType relationType = RelationType.GetByAlias("relateMemberToGalleryDocType");
            apiRelation.Relation[] relation = apiRelation.Relation.GetRelations(id, relationType);
            if (relation.Count() != 0)
            {
                Node node = new Node(relation[0].Child.Id);
                List<Node> nodes = NodeHelper.GetNodesByAliasType(node, "sfImageEntry");
                List<Image> images = ConvertNodesToImages(nodes);
                return images;
            }
            return null;
        }

        public override List<Image> GetImagesByMember(Member member)
        {
            return GetImagesByMember(member.Id);
        }

        public override List<Image> GetImagesByMember(int id, int? pageSize, int page)
        {
            RelationType relationType = RelationType.GetByAlias("relateMemberToGalleryDocType");
            apiRelation.Relation[] relation = apiRelation.Relation.GetRelations(id, relationType);
            if (relation.Count() != 0)
            {
                Node node = new Node(relation[0].Child.Id);
                List<Node> nodes = NodeHelper.GetNodesByAliasType(node, "sfImageEntry");
                List<Image> images = ConvertNodesToImages(nodes);
                if (pageSize.HasValue)
                    images =
                        images.OrderByDescending(blog => blog.CreatedDate).Skip((page - 1)*pageSize.Value).Take(pageSize.Value).
                            ToList();

                return images;
            }
            return null;
        }

        public override List<Image> GetImagesByMember(Member member, int? pageSize, int page)
        {
            return GetImagesByMember(member.Id, pageSize, page);
        }

        public override List<Image> GetImagesByMember(int id, int? pageSize, int page, out int total)
        {
            throw new NotImplementedException();
        }

        public override List<Image> GetImagesByMember(Member member, int? pageSize, int page, out int total)
        {
            throw new NotImplementedException();
        }

        public override string GetMemberImageUrl(int memberId)
        {
            return GetMemberImageUrl(MemberProvider.Provider.GetMemberById(memberId));
        }

        public override string GetMemberImageUrl(Member member)
        {
            RelationType relationType = RelationType.GetByAlias("relateMemberToGalleryDocType");
            apiRelation.Relation[] relation = apiRelation.Relation.GetRelations(member.Id, relationType);
            if (relation.Count() != 0)
            {
                return umbraco.library.NiceUrl(relation[0].Child.Id);
            }
            return null;
        }

        private static Image ConvertNodeToImage(Node node)
        {
            Image image = new Image();

            image.Id = node.Id;
            image.ModifiedDate = node.UpdateDate;
            image.CreatedDate = node.CreateDate;
            image.Title = node.GetProperty("title").Value;
            image.Content = node.GetProperty("content").Value;
            image.PageUrl = library.NiceUrl(node.Id);
            image.Tags = TagProvider.Provider.GetTags(node.Id);
            if (node.GetProperty("mediaItem") != null)
            {
                image.Media = MediaProvider.Provider.GetMediaById(Convert.ToInt32(node.GetProperty("mediaItem").Value));
                //Media m = new Media(image.MediaId);
                //image.MediaUrl = m.getProperty("umbracoFile").Value.ToString();
            }
            //RelationType relationType = RelationType.GetByAlias("relateMemberToMemberDocType");
            apiRelation.Relation[] relations = apiRelation.Relation.GetRelations(node.Parent.Id);//, relationType);
            if(relations.Count() == 1)
                image.Member = MemberProvider.Provider.GetMemberById(relations[0].Parent.Id);

            return image;
        }

        private static List<Image> ConvertNodesToImages(List<Node> nodes)
        {
            List<Image> images = new List<Image>();
            foreach (Node node in nodes)
            {
                images.Add(ConvertNodeToImage(node));
            }
            return images;
        }
    }
}